package edu.syr.iis.web.model;

import java.sql.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;

import edu.syr.iis.web.util.HibernateUtil;

public class AnnotationSessionManager {
	
	/**
	 * Returns list of all AnnotationSession database records sorted by userId
	 */
	public List<AnnotationSession> getAnnotationSessions()
	{
		List<AnnotationSession> list = null;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			list = session.createQuery("FROM AnnotationSession").list();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return list;
	}
	
	public List<AnnotationSession> getAnnotationSessions(User user)
	{
		List<AnnotationSession> list = null;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			list = session
			.createQuery("FROM AnnotationSession WHERE user = :user")
			.setEntity("user", user)
			.list();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return list;
	}

	public List<AnnotationSession> getAnnotationSessions(Date startDateTime, Date endDateTime)
	{
		List<AnnotationSession> list = null;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			list = session
			.createQuery("FROM AnnotationSession" +
					     " WHERE startDateTime > :startDateTime" +
					     " AND endDateTime < :endDateTime" + 
					     " ORDER BY user")			
			.setString("startDateTime", startDateTime.toString())
			.setString("endDateTime", endDateTime.toString())
			.list();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return list;
	}
	
	public List<AnnotationSession> getAnnotationSessions(User user, Date startDateTime, Date endDateTime)
	{
		List<AnnotationSession> list = null;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		try
		{
			list = session
			.createQuery("FROM AnnotationSession WHERE user = :user" +
					     " AND startDateTime > :startDateTime" +
					     " AND endDateTime < :endDateTime")
			.setEntity("user", user)
			.setString("startDateTime", startDateTime.toString())
			.setString("endDateTime", endDateTime.toString())
			.list();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
		return list;
	}
	
	
	
	
	public AnnotationSession getNewAnnotationSession(User user)
	{
		AnnotationSession as = new AnnotationSession();
		as.setUser(user);
		as.setStartDateTime(new Date(new java.util.Date().getTime()));		
		saveAnnotationSession(as);
		
		return as;
	}
	/**
	 * Saves a AnnotationSession object.
	 */
	public void saveAnnotationSession(AnnotationSession annotationSession)
	{
		Session session = HibernateUtil.getSessionFactory()
		.getCurrentSession();
		session.beginTransaction();
		try
		{
			session.saveOrUpdate(annotationSession);
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
	}
	
	/**
	 * Deletes AnnotationSession record with matching AnnotationSessionId 
	 */
	public void deleteAnnotationSession(int annotationSessionId)
	{
		Session session = 
			HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();	
		try
		{
			Object toDelete = session.get(AnnotationSession.class,new Integer(annotationSessionId));

			if (toDelete != null) { 
				session.delete(toDelete);
			}

			session.flush();
			session.getTransaction().commit();
		}
		catch (HibernateException e)
		{
			session.getTransaction().rollback();
			throw e;
		}
	}
	
	public AnnotationSessionStatistics getStat(User user, Date startDateTime, Date endDateTime)
	{		
		AnnotationSessionStatistics stat = new  AnnotationSessionStatistics();
		List<AnnotationSession> annotationSessions = this.getAnnotationSessions(user, startDateTime, endDateTime);
		
		long totalDuration = 0;		
		int numOfSessions = 0;
		
		for (AnnotationSession annotationSession: annotationSessions)
		{
			totalDuration += annotationSession.getDuration();
			numOfSessions++;
			if (stat.getUser() == null && annotationSession.getUser() != null)
				stat.setUser(annotationSession.getUser());
		}
		
		stat.setStartDateTime(startDateTime);
		stat.setEndDateTime(endDateTime);
		stat.setNumOfSessions(numOfSessions);
		stat.setTotalDuration(totalDuration);
		
		return stat;		
	}

}
